use axum::Json;
use sea_orm::{ConnectionTrait, DbBackend, Statement, FromQueryResult};
use serde_json::Value;
use crate::{code, encrypt, query, reqwest, sea_orm::{connect, send_sql_ok}};
use serde::{ Deserialize, Serialize };
#[derive(Debug, Deserialize, Serialize, FromQueryResult)]
pub struct Data { }
// 基础 token
// 生成 access_token
async fn create_access_token(appid:&str, secret:&str)-> Result<String, Json<Value>>{
    let url = format!("https://api.weixin.qq.com/cgi-bin/token?appid={appid}&secret={secret}&grant_type=client_credential");
    let rs = reqwest::get(&url).await?;
    if let Some(f) = query::str_op(&rs, "access_token")? {
        Ok(f)
    }else {
        Err(code::err_("access_token 获取失败"))
    }
}

pub async fn insert_access_token(appid:&str, secret:&str) -> Result<Json<Value>, Json<Value>>{
    
    let conn = connect().await?;

    let stmt = Statement::from_string(
        DbBackend::MySql,
        format!("select count(*) as count from access_token")
    );

    let result = Data::find_by_statement(stmt).into_json().one(&conn).await.unwrap_or_default().unwrap_or_default();

    let count = query::u8(&result, "count")?;
    if count > 0 {
        return code::err("access_token 已存在");
    }

    let token = create_access_token(appid, secret).await?;

    let token = encrypt::magic_crypt::encode_256(&token);

    let stmt = Statement::from_string(
        DbBackend::MySql,
        format!("insert into access_token set token='{token}'")
    );
    send_sql_ok(&conn,conn.execute(stmt).await).await
}

pub async fn update_access_token(appid:&str, secret:&str) -> Result<Json<Value>, Json<Value>>{
    let token = create_access_token(appid, secret).await?;
    let token = encrypt::magic_crypt::encode_256(&token);
    let conn = connect().await?;
    let stmt = Statement::from_string(
        DbBackend::MySql,
        format!("update access_token set token='{token}' where id=1")
    );
    send_sql_ok(&conn,conn.execute(stmt).await).await
}

pub async fn token() -> Result<String, Json<Value>>{
    let conn = connect().await?;
    let stmt = Statement::from_string(
        DbBackend::MySql,
        format!("select token from access_token where id=1")
    );

    let result = Data::find_by_statement(stmt).into_json().one(&conn).await.unwrap_or_default();
    if let Some(f) = result {
        let token = query::str(&f, "token")?;
        let token = encrypt::magic_crypt::decode_256(&token)?;
        Ok(token)
    }else{
        Err(code::err_("access_token 不存在"))
    }
}